package org.example.MedicalCrowdsourcing.service;

import org.example.MedicalCrowdsourcing.model.entity.Permission;
import org.example.MedicalCrowdsourcing.model.entity.Role;
import org.example.MedicalCrowdsourcing.model.entity.RolePermission;
import org.example.MedicalCrowdsourcing.repository.PermissionRepository;
import org.example.MedicalCrowdsourcing.repository.RolePermissionRepository;
import org.example.MedicalCrowdsourcing.repository.RoleRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 权限管理服务
 */
@Service
public class PermissionService {
    private static final Logger logger = LoggerFactory.getLogger(PermissionService.class);

    @Autowired
    private PermissionRepository permissionRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private RolePermissionRepository rolePermissionRepository;

    /**
     * 初始化权限和角色权限关系
     */
    @PostConstruct
    @Transactional
    public void initPermissions() {
        // 创建预定义权限
        createPermissionIfNotExists(Permission.VIEW_PROJECTS, "查看项目列表");
        createPermissionIfNotExists(Permission.CREATE_PROJECT, "创建新项目");
        createPermissionIfNotExists(Permission.EDIT_PROJECT, "编辑项目");
        createPermissionIfNotExists(Permission.DELETE_PROJECT, "删除项目");
        createPermissionIfNotExists(Permission.MANAGE_USERS, "管理用户");
        createPermissionIfNotExists(Permission.UPLOAD_DATA, "上传数据");
        createPermissionIfNotExists(Permission.DOWNLOAD_DATA, "下载数据");
        createPermissionIfNotExists(Permission.MANAGE_BLOCKCHAIN, "管理区块链数据");
        createPermissionIfNotExists(Permission.ADMIN_ACCESS, "管理员权限");

        // 分配角色权限
        assignInitialPermissions();
    }

    /**
     * 如果权限不存在则创建
     */
    private Permission createPermissionIfNotExists(String name, String description) {
        if (!permissionRepository.existsByName(name)) {
            Permission permission = new Permission();
            permission.setName(name);
            permission.setDescription(description);
            Permission saved = permissionRepository.save(permission);
            logger.info("创建权限: {}", name);
            return saved;
        }
        return permissionRepository.findByName(name).orElse(null);
    }

    /**
     * 为各角色分配初始权限
     */
    private void assignInitialPermissions() {
        // 获取所有角色
        Optional<Role> researcher = roleRepository.findById(Role.RESEARCHER);
        Optional<Role> participant = roleRepository.findById(Role.PARTICIPANT);
        Optional<Role> admin = roleRepository.findById(Role.ADMIN);

        // 研究者权限
        if (researcher.isPresent()) {
            assignPermissionToRole(researcher.get(), Permission.VIEW_PROJECTS);
            assignPermissionToRole(researcher.get(), Permission.CREATE_PROJECT);
            assignPermissionToRole(researcher.get(), Permission.EDIT_PROJECT);
            assignPermissionToRole(researcher.get(), Permission.UPLOAD_DATA);
            assignPermissionToRole(researcher.get(), Permission.DOWNLOAD_DATA);
        }

        // 参与者权限
        if (participant.isPresent()) {
            assignPermissionToRole(participant.get(), Permission.VIEW_PROJECTS);
            assignPermissionToRole(participant.get(), Permission.UPLOAD_DATA);
        }

        // 管理员权限
        if (admin.isPresent()) {
            assignPermissionToRole(admin.get(), Permission.VIEW_PROJECTS);
            assignPermissionToRole(admin.get(), Permission.CREATE_PROJECT);
            assignPermissionToRole(admin.get(), Permission.EDIT_PROJECT);
            assignPermissionToRole(admin.get(), Permission.DELETE_PROJECT);
            assignPermissionToRole(admin.get(), Permission.MANAGE_USERS);
            assignPermissionToRole(admin.get(), Permission.UPLOAD_DATA);
            assignPermissionToRole(admin.get(), Permission.DOWNLOAD_DATA);
            assignPermissionToRole(admin.get(), Permission.MANAGE_BLOCKCHAIN);
            assignPermissionToRole(admin.get(), Permission.ADMIN_ACCESS);
        }
    }

    /**
     * 为角色分配权限
     */
    @Transactional
    public void assignPermissionToRole(Role role, String permissionName) {
        Optional<Permission> permission = permissionRepository.findByName(permissionName);
        if (permission.isPresent() && !rolePermissionRepository.existsByRoleAndPermission(role, permission.get())) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRole(role);
            rolePermission.setPermission(permission.get());
            rolePermissionRepository.save(rolePermission);
            logger.info("为角色 {} 分配权限: {}", role.getName(), permissionName);
        }
    }

    /**
     * 检查角色是否拥有指定权限
     */
    public boolean hasPermission(Integer roleId, String permissionName) {
        return rolePermissionRepository.hasPermission(roleId, permissionName);
    }

    /**
     * 获取角色所有权限
     */
    public List<String> getRolePermissions(Integer roleId) {
        return rolePermissionRepository.findPermissionsByRoleId(roleId).stream()
                .map(Permission::getName)
                .collect(Collectors.toList());
    }

    /**
     * 删除角色权限
     */
    @Transactional
    public void removePermissionFromRole(Role role, String permissionName) {
        Optional<Permission> permission = permissionRepository.findByName(permissionName);
        if (permission.isPresent()) {
            Optional<RolePermission> rolePermission = 
                    rolePermissionRepository.findByRoleAndPermission(role, permission.get());
            rolePermission.ifPresent(rp -> rolePermissionRepository.delete(rp));
        }
    }
} 